<template>
  <q-page class="q-pa-md">
    <div style="position: relative">
      <q-breadcrumbs
        class="q-mb-md"
        style="height: 50px; line-height: 40px; border-bottom: 1px dashed #ccc"
      >
        <el-icon style="cursor: pointer" @click="router.go(-1)">
          <ArrowLeft />
        </el-icon>
        <q-breadcrumbs-el label="模型仓库" />
        <q-breadcrumbs-el label="模型版本对比" />
      </q-breadcrumbs>
      <el-tabs type="border-card" @tab-change="tabChange">
        <el-tab-pane label="Parallel Coordinates Plot" class="tab1">
          <div class="content—left">
            <el-form :label-position="'top'" :model="form" label-width="120px">
              <el-form-item label="Parameters:">
                <el-select
                  multiple
                  v-model="form.ModelParameter"
                  placeholder="please select your zone"
                  @change="tab1Parameter"
                  @remove-tag="removeLabels"
                  style="width: 300px"
                >
                  <el-option
                    v-for="(item, value) in parameterSelectData"
                    :key="item"
                    :label="value"
                    :value="value"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="Metrics:">
                <el-select
                  multiple
                  v-model="form.Metrics"
                  placeholder="please select your zone"
                  @change="tab1Metrics"
                  @remove-tag="removeLabels"
                  style="width: 300px"
                >
                  <el-option
                    v-for="(item, value) in versionEvaluationSelectData"
                    :key="item"
                    :label="value"
                    :value="value"
                  />
                </el-select>
              </el-form-item>
            </el-form>
          </div>
          <div class="content-right">
            <chart-line v-show="chartOption.parallelAxis.length === 1" :chartOption="chartOption2" :chartSize="chastSize"></chart-line>
            <chart-line
              v-show="chartOption.parallelAxis.length > 1"
              :chartOption="chartOption"
              :chartSize="chastSize"
            ></chart-line>
          </div>
        </el-tab-pane>
        <el-tab-pane label="Scatter Plot" class="tab1">
          <div class="content—left">
            <el-form :label-position="'top'" :model="formTwo" label-width="120px">
              <el-form-item label="X-axis:">
                <el-select v-model="formTwo.selectValueData1" @change="form3Change">
                  <el-option-group
                    v-for="group in options1"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.options"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
              <el-form-item label="Y-axis:">
                <el-select v-model="formTwo.selectValueData2" @change="form3Change">
                  <el-option-group
                    v-for="group in options2"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.options"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
            </el-form>
          </div>
          <div class="content-right">
            <chart-line v-if="formTwo.selectValueData1 && formTwo.selectValueData2" :chartOption="chartOption3" :chartSize="chastSize"></chart-line>
          </div>
        </el-tab-pane>
        <el-tab-pane label="Box Plot">
          <div class="content—left">
            <el-form :label-position="'top'" :model="formScatterAndLineChart" label-width="120px">
              <el-form-item label="X-axis:">
                <el-select v-model="formScatterAndLineChart.form1" @change="formChangeScatterAndLineChartHandle">
                  <el-option-group
                    v-for="group in options1"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.options"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
              <el-form-item label="Y-axis:">
                <el-select v-model="formScatterAndLineChart.form2" @change="formChangeScatterAndLineChartHandle">
                  <el-option-group
                    v-for="group in options2"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.options"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
            </el-form>
          </div>
          <div class="content-right">
            <chart-line v-if="chartOption4Show" :chartOption="chartOption4" :chartSize="chastSize"></chart-line>
          </div>
        </el-tab-pane>
        <el-tab-pane label="Contour Plot" class="Plot">
          <div class="content—left">
            <el-form :label-position="'top'" :model="formScatterAndLineChart" label-width="120px">
              <el-form-item label="X-axis:">
                <el-select v-model="chart3d.formX" @change="select3Changed">
                  <el-option-group
                    v-for="group in options1"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.options"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
              <el-form-item label="Y-axis:">
                <el-select v-model="chart3d.formY" @change="select3Changed">
                  <el-option-group
                    v-for="group in options2"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.options"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
              <el-form-item label="Z-axis:">
                <el-select v-model="chart3d.formZ" @change="select3Changed">
                  <el-option-group
                    v-for="group in options2"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.options"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
            </el-form>
          </div>
          <div class="content-right">
            <div id="hello" style="height: 400px;width: 700px;margin-bottom: 20px"></div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
  </q-page>
</template>
<script setup>
//离散点转换等高线 start
import * as Plot from "@observablehq/plot";
import * as d3 from "d3"
import $ from "jquery"
// end
import {modelStore} from "stores/model";
const showModelStore = modelStore()
import {useRouter} from "vue-router";
const router = useRouter()
import { getModelVersionParameter,getModelVersionEvaluationData } from 'src/api/model'
import * as echarts from 'echarts'
import ecStat from 'echarts-stat';
import chartLine from 'src/components/chartLine.vue';
echarts.registerTransform(ecStat.transform.clustering);
import {reactive, ref} from "vue";
import {toNumber} from "lodash";
import ChartLine from "components/chartLine.vue";
const chastSize = reactive({
  width: '900px',
  height: "350px"
})
const form = reactive({
  ModelParameter: [],
  Metrics: [],
})
const formTwo = reactive({
  selectValueData1: '',
  selectValueData2: ''
})
const chart3d = reactive({
  formX:'',
  formY:'',
  formZ:'',
})
const formScatterAndLineChart = reactive({
  form1: '',
  form2: ''
})



//第一个tab start
const chartOption = reactive({
  parallelAxis: [],
  visualMap: {
    show: true,
    min: 0,
    max: 20,
    right: 0,
    bottom: 150,
    dimension: 1,
    inRange: {
      color: ['#d94e5d', '#eac736', '#50a3ba'].reverse()
    }
  },
  series: []
})
const chartOption2 = reactive({
  xAxis: {
    show: false,
    splitLine:{
      show:false // 不显示网格线
    },
  },
  yAxis: {
    splitLine:{
      show:false // 不显示网格线
    },
  },
  series: [
    {
      symbolSize: 20,
      data: [],
      type: 'scatter'
    }
  ]
})
const tab1Parameter = (electData) => {
  addChart1(electData,chart1_Parameter.value);
}
const tab1Metrics = (electData) => {
  addChart1(electData,chart1_versionEvaluation.value);
}
let chartOption2Show = ref(false);
const addChart1 = (electData,valueData) => {
  if(electData.length == 0) return;
  let data = JSON.parse(JSON.stringify(valueData));
  let dataArray = data.map( da => toNumber(da[electData[0]]))
  if( chartOption.parallelAxis.length === 0 ){
    let circleNumbers = -1;
    let MaxData = Math.max.apply(null, dataArray);//获取数组最大值
    dataArray.forEach( (value,index) =>{
      chartOption.series[index].data[0].push(value)
    })
    for( let items in totalData.value ){
      circleNumbers++;
      chartOption2.series[0].data[circleNumbers][0] = 0
      chartOption2.series[0].data[circleNumbers][1] = toNumber(totalData.value[items][electData[0]]);
    }
    chartOption.parallelAxis.push({
      dim: 0,
      max: 10,
      name: electData[0]
    })
    chartOption2Show.value = !chartOption2Show.value
  }else{
    for(let task of electData){
      const itemJson = chartOption.parallelAxis.findIndex((item)=>{return item.name == task});
      if( itemJson === -1 ){
        let lg = chartOption.parallelAxis.length+1;
        chartOption.parallelAxis.push({
          dim: lg++,
          max: 10,
          name: task
        })
        let dataArray = data.map( da => toNumber(da[task]))
        dataArray.forEach( (value,index) =>{
          chartOption.series[index].data[0].push(value)
        })
      }
    }
  }
};
const removeLabels = (val) => {
  const itemIndex = chartOption.parallelAxis.findIndex(item => item.name ==val);
  chartOption.parallelAxis.splice(itemIndex,1);
  chartOption.series.forEach( item => {
    item.data[0].splice(itemIndex,1);
  })
  if( chartOption.parallelAxis.length === 1 ){
    let newData = [];
    chartOption.series.forEach( item => {
      newData.push(item.data[0]);
    })
    newData.forEach( (item,index) => {
      chartOption2.series[0].data[index][0] = 0
      chartOption2.series[0].data[index][1] = item;
    })
  }
}
const options1 = reactive([
  {
    label: 'Parameters:',
    id: 0,
    options: [
      {
        value: 'alpha',
        label: 'alpha',
      },
      {
        value: 'l1_ratio',
        label: 'l1_ratio',
      }
    ],
  },
  {
    label: 'Metrics:',
    id: 1,
    options: [
      {
        value: 'mae',
        label: 'mae',
      },
      {
        value: 'r2',
        label: 'r2',
      },
      {
        value: 'rmse',
        label: 'rmse',
      }
    ],
  },
])
const options2 = reactive([
  {
    label: 'Parameters:',
    id: 0,
    options: [
      {
        value: 'alpha',
        label: 'alpha',
      },
      {
        value: 'l1_ratio',
        label: 'l1_ratio',
      }
    ],
  },
  {
    label: 'Metrics:',
    id: 1,
    options: [
      {
        value: 'mae',
        label: 'mae',
      },
      {
        value: 'r2',
        label: 'r2',
      },
      {
        value: 'rmse',
        label: 'rmse',
      }
    ],
  },
])
//第一个tab end


//第二个tab start
const chartOption3 = reactive({
  grid: {
    top: 30,
    left: 30,
    right: 30,
    bottom: 30,
    containLabel: true
  },
  xAxis: {
    name: '',
    nameLocation: "center",
    nameGap: 30,
    nameRotate: '0',
  },
  yAxis: {
    name: '',
    nameLocation: "center",
    nameGap: 30,
    nameRotate: '0',
  },
  // yAxis: [{
  //   name: '',
  //   nameLocation: "center",
  //   nameGap: 30,
  //   nameRotate: '90',
  //   axisLabel: {
  //     show: true,
  //     textStyle: {
  //       color: '#595C61'
  //     },
  //     rotate: 45
  //   },
  //   axisLine: {
  //     show: true
  //   }
  // }],
  series: [
    {
      symbolSize: 20,
      data: [],
      type: 'scatter'
    }
  ]
})
function drawDesigns (form1,form2) {
  if( formTwo.selectValueData1 && formTwo.selectValueData2 ){
    let circleNumbers = -1;
    chartOption3.xAxis.name = form1;
    chartOption3.yAxis.name = form2;
    for( let items in totalData.value ){
      circleNumbers++;
      chartOption3.series[0].data[circleNumbers][0] = toNumber(totalData.value[items][form1])
      chartOption3.series[0].data[circleNumbers][1] = toNumber(totalData.value[items][form2])
    }
  }
}
function form3Change(){
  drawDesigns(formTwo.selectValueData1,formTwo.selectValueData2);
}
//第二个tab end


//第四个tab
let data = ref([]);
let chart3Show = ref(false)
function draw(data) {
  let ps = Plot.plot({
    color: {legend: true,scheme: "sinebow"},
    marks: [
      Plot.contour(data, {x: "x", y: "y", fill: "z", blur: -1, stroke: "black"}),
      Plot.dot(data, {x: "x", y: "y", channels: {z: "z"}, tip: true}),
      Plot.frame(),
      Plot.text(["图1"], {frameAnchor: "top-right",dy: -15,fontSize:15,fontWeight:900}),
    ]
  })

  $("#hello").append(ps);
}
function select3Changed () {
  if( chart3d.formX && chart3d.formY && chart3d.formZ ){
    chart3Show.value = true;
    for( let items in totalData.value ){
      data.value.push({
        x: toNumber(totalData.value[items][chart3d.formX]),
        y: toNumber(totalData.value[items][chart3d.formY]),
        z: toNumber(totalData.value[items][chart3d.formZ])
      })
    }
    draw(data.value);
  }
}

let parameterSelectData = ref([]);
let versionEvaluationSelectData = ref([]);
let tab2Parameter = reactive([]);
let tab2VersionEvaluation = reactive([]);

let chart1_Parameter = ref([]);
let chart1_versionEvaluation = ref([]);

let totalData = ref({});
getModelVerParameter();
function getModelVerParameter(){
  let versions = showModelStore.getCompareModelVersions;
  for( let i = 0; i< versions.length; i++ ){
    let key = versions[i];
    totalData.value[key] = {}
  }
  const projectId = router.currentRoute.value.params.project_id
  const repository_model_id = showModelStore.repository_model_id
  versions.forEach(items=>{
    getModelVersionParameter(projectId,repository_model_id,items).then(res =>{
      parameterSelectData.value = res.data;
      chart1_Parameter.value.push(res.data);
      tab2Parameter.push(res.data)

      if(totalData.value.hasOwnProperty(items)){
        Object.assign(totalData.value[items],res.data)
      }
    })
    getModelVersionEvaluationData(projectId,repository_model_id,items).then(res =>{
      versionEvaluationSelectData.value = res.data;
      chart1_versionEvaluation.value.push(res.data);

      tab2VersionEvaluation.push(res.data)

      if(totalData.value.hasOwnProperty(items)){
        Object.assign(totalData.value[items],res.data)
      }
    })
  })
}
function tabChange (val) {
  if( val === '1' ){
    form3Change()
  }
}

function checkValue(arr,value){
  return arr.some(obj => {
    if(obj.hasOwnProperty(value)){
      return true
    }else {
      return false
    }
  })
}
const chartOption4 = reactive({
  legend: {
    data: ['xxx', 'yyy'],
    orient: 'horizontal',
    x: 'right',
    y: ' center'
  },
  grid: {
    top: 30,
    left: 30,
    right: 30,
    bottom: 30,
    containLabel: true
  },
  xAxis: [
    {
      type: 'category',
      name: '',
      nameLocation: "center",
      nameGap: 20,
      data: [
        '',
        '',
        '',
        ''
      ],
      axisPointer: {
        type: 'shadow'
      },
      axisLabel: {
        show: true,
        textStyle: {
          color: '#595C61'
        },
      },
      axisLine: {
        show: false
      }
    }
  ],
  yAxis: [
    {
      type: 'value',
      name: '',
      nameLocation: "center",
      nameGap: 30,
      nameRotate: '90',
      max: 1,
      axisLabel: {
        show: true,
        textStyle: {
          color: '#595C61'
        },
        rotate: 45
      },
      axisLine: {
        show: true
      }
    }
  ],
  series: []
})
function addValueScatterAndLineChartHandle(arrayList,value){
  let tab2Name = arrayList.map( item => {
    if( item[value] ){
      return toNumber(item[value])
    }
  });
  for(let i = 1; i < tab2Name.length; i++){
    chartOption4.series.push({
      type: 'scatter',
      data:[tab2Name[i]],
      color: '#32C5FF',
      symbolSize: 12
    })
    chartOption4.series.push({
      type: 'line',
      symbol: 'none',
      data:['', tab2Name[i], tab2Name[i], tab2Name[i]],
      color: '#32C5FF',
      symbolSize: 12
    })
  }
}
let chartOption4Show = ref(false);
function formChangeScatterAndLineChartHandle(){
  const tab2Param = JSON.parse(JSON.stringify(tab2Parameter))
  const tab2VersionEval = JSON.parse(JSON.stringify(tab2VersionEvaluation))
  if( formScatterAndLineChart.form1 && formScatterAndLineChart.form2 ){
    chartOption4Show.value = true;
    chartOption4.series = [];
    chartOption4.xAxis[0].name = formScatterAndLineChart.form1;
    chartOption4.yAxis[0].name = formScatterAndLineChart.form2;
    let result = checkValue(tab2Param,formScatterAndLineChart.form1);
    let result1 = checkValue(tab2VersionEval,formScatterAndLineChart.form2);
    if( result ){
      addValueScatterAndLineChartHandle(tab2Param,formScatterAndLineChart.form1);
    }else {
      addValueScatterAndLineChartHandle(tab2VersionEval,formScatterAndLineChart.form1);
    }
    if( result1 ){
      addValueScatterAndLineChartHandle(tab2VersionEval,formScatterAndLineChart.form2);
    }else {
      addValueScatterAndLineChartHandle(tab2Param,formScatterAndLineChart.form2);
    }
  }
}
let chartInit = () => {
  let versionlg = showModelStore.getCompareModelVersions.length;
  for( let i = 0;i<versionlg;i++){
    //根据对比版本数量确定要画多少条线
    chartOption.series.push({
      type: 'parallel',
      lineStyle: {
        width: 1,
        opacity: 0.5
      },
      data:[
        []
      ]
    })
    chartOption2.series[0].data.push([]);
    chartOption3.series[0].data.push([]);
  }
}
chartInit();

</script>

<style lang="scss" scoped>

.Plot{
  display: flex;
  justify-content: space-between;
  &.div{
    flex: 1;
  }
}
.tab1 {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  &div:nth-child(1) {
    flex: 1;
  }
  &div:nth-child(2) {
    flex: 3;
  }
}
* { touch-action: pan-y; }

.but {
  position: absolute;
  top: 20px;
  left: 70px;
}
</style>
